import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

import { registerMicroApps, start } from 'qiankun';
import * as EventEmitter from 'events';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch((err) => console.error(err));

registerMicroApps([
  {
    name: 'vueElement1',
    entry: '//localhost:7001',
    container: '#vueElement1',
    activeRule: () => true,
  },
  // {
  //   name: 'vueElement2',
  //   entry: '//localhost:7002',
  //   container: '#vueElement2',
  //   activeRule: () => true,
  // },
  // {
  //   name: 'vueAnt1',
  //   entry: '//localhost:8001',
  //   container: '#vueAnt1',
  //   activeRule: () => true,
  // },
  // {
  //   name: 'vueAnt2',
  //   entry: '//localhost:8002',
  //   container: '#vueAnt2',
  //   activeRule: () => true,
  // },
]);
// 启动 qiankun
start({
  singular: false,
  sandbox: {
    // strictStyleIsolation: true,
    // experimentalStyleIsolation: true,
  },
});

export type QKIpcConfig = {
  // 超时时间
  timeout?: number;
};

export type QKIpcMessage<T = any> = {
  // 请求目标
  api: string;
  // 携带信息
  data: T;
};

// -----------------------------------------------------------------------------------------------------------------------------------------------
/**
 * qiankun 通讯注册中心
 */
class QKIpcRegisterCenter {
  // 注册队列
  private _registerQueue = new Map<string, QKIpc>();

  /**
   * 注册消息通信管道
   * @param projectName 项目名称
   * @param config 同信配置
   * @returns 通信管道
   */
  register(projectName: string, config: QKIpcConfig): QKIpc {
    if (!this._registerQueue.has(projectName)) {
      this._registerQueue.set(projectName, new QKIpc(projectName, config));
    }
    return this._registerQueue.get(projectName);
  }

  /**
   * 目标项目是否存活
   * @param projectName 项目名称
   * @returns
   */
  isActivity(projectName: string): boolean {
    return this._registerQueue.has(projectName);
  }

  /**
   * 获取指定的通讯管道
   * @param projectName 项目名称
   * @returns
   */
  getQKIpc(projectName: string): QKIpc {
    return this._registerQueue.get(projectName);
  }

  /**
   * 广播消息
   * @param msg 消息
   */
  sendAll(msg: QKIpcMessage): void {
    this._registerQueue.forEach((value) => {
      value.send(msg);
    });
  }
}

/**
 * qiankun 通信管道
 */
class QKIpc {
  // 所属项目
  projectName: string;

  // 超时时间
  timeout: number;

  constructor(projectName: string, config?: QKIpcConfig) {
    this.timeout = config?.timeout || 3000;
    this.projectName = projectName;
  }

  /**
   * 发送消息
   * @param msg 消息
   * @param option 发送选项
   * @returns 发送结果
   */
  send<T>(
    msg: QKIpcMessage,
    option?: { timeout?: number }
  ): Promise<QKIpcMessage<T>> {
    return new Promise<QKIpcMessage<T>>((resolve, reject) => {
      // 是否已经处理
      let isHandle = false;

      // 调用处理
      this.handle(msg)
        .then((res) => !isHandle && resolve(res))
        .catch((err) => !isHandle && reject(err))
        .finally(() => (isHandle = true));

      setTimeout(() => {
        if (!isHandle) {
          isHandle = true;
          reject(new Error('send timeout'));
        }
      }, option?.timeout || this.timeout);
    });
  }

  /**
   * @cover 消息处理
   * @param msg 消息
   * @returns 处理结果
   */
  handle(msg: QKIpcMessage): Promise<QKIpcMessage> {
    return new Promise((resolve) => {
      resolve(msg);
    });
  }
}

const qKIpcRegisterCenter = new QKIpcRegisterCenter();

window['QKIpcRegisterCenter'] = qKIpcRegisterCenter;

setTimeout(() => {
  qKIpcRegisterCenter
    .getQKIpc('qiankun-vue-element-children-1')
    .send({
      api: 'test',
      data: {
        text: '测试-1',
      },
    })
    .then((res) => {
      console.log('主应用接收到消息', res);
    })
    .catch((err) => {
      console.error('主应用接收到消息', err);
    });
  qKIpcRegisterCenter
    .getQKIpc('qiankun-vue-element-children-1')
    .send({
      api: 'test',
      data: {
        text: '测试0',
      },
    })
    .then((res) => {
      console.log('主应用接收到消息', res);
    })
    .catch((err) => {
      console.error('主应用接收到消息', err);
    });
  qKIpcRegisterCenter
    .getQKIpc('qiankun-vue-element-children-1')
    .send(
      {
        api: 'test',
        data: {
          text: '测试1',
        },
      },
      {
        timeout: 5000,
      }
    )
    .then((res) => {
      console.log('主应用接收到消息', res);
    })
    .catch((err) => {
      console.error('主应用接收到消息', err);
    });
  qKIpcRegisterCenter
    .getQKIpc('qiankun-vue-element-children-1')
    .send({
      api: 'test',
      data: {
        text: '测试2',
      },
    })
    .then((res) => {
      console.log('主应用接收到消息', res);
    })
    .catch((err) => {
      console.error('主应用接收到消息', err);
    });
  qKIpcRegisterCenter
    .getQKIpc('qiankun-vue-element-children-1')
    .send({
      api: 'test',
      data: {
        text: '测试3',
      },
    })
    .then((res) => {
      console.log('主应用接收到消息', res);
    })
    .catch((err) => {
      console.error('主应用接收到消息', err);
    });
}, 6000);
